# VideoScreen - This screen allows user to browse video library content
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import os
import gtk
import pango
import clutter

from frontend.gui.screens.screen import Screen
from frontend.gui.transitions.transition import Transition

# Widgets
from frontend.gui.widgets.tabs_menu import TabsMenu
from frontend.gui.widgets.image_menu import ImageMenu
from frontend.gui.widgets.list_indicator import ListIndicator
from frontend.gui.widgets.image_menu_item import ImageMenuItem
from frontend.gui.widgets.justified_text_menu_item import JustifiedTextMenuItem

# Video library
from frontend.medialibrary.videos import Movie
from frontend.medialibrary.videos import TVSeries
from frontend.medialibrary.videos import VideoClip
from frontend.medialibrary.videos import VideoLibrary

class VideoScreen(Screen):
    """
    VideoScreen
    
    This screen contains tabs for different video types. This is the top level
    UI for video library.
    """
    
    def __init__(self, ui, frontend):
        """
        Initialize screen
        
        @param frontend: FrontendClient object
        @param theme: Theme object
        """
        self.ui = ui
        self.frontend = frontend
        self.theme = frontend.getTheme()
        self.group = clutter.Group()
        self.library = self.frontend.get_video_library()
        
        # Screen Title (Displayed at the bottom left corner)
        self.screen_title = clutter.Label()
        self.screen_title.set_font_name(self.theme.getFont() + ' 100px')
        self.screen_title.set_color(self.theme.getColor("screentitle"))
        self.screen_title.set_text("Videos")
        self.screen_title.set_name("screen_title")
        
        (screen_title_width, screen_title_height) = self.screen_title.get_size()
        screen_title_x = 0
        screen_title_y = ui.STAGE_HEIGHT - screen_title_height + 20
        
        self.screen_title.set_position(screen_title_x, screen_title_y)
        self.screen_title.show()
        self.group.add(self.screen_title)
        
        # Create tabs
        self._create_tabs()
        self._create_movies_tab()
        self._create_series_tab()
        self._create_music_videos_tab()
        self._create_clips_tab()
        
        self.current_tab = "movies"
        self.movies_tab.show()
        
        self.group.show()
        ui.getStage().add(self.group)
    
    def _create_tabs(self):
        """
        Create tab bar of the screen. Tabs: Movies, TV-Series, Video clips
        """
        self.tabs = TabsMenu(self.theme, 
                        self.frontend.get_configuration().show_effects())
        self.tabs.set_item_size(400, 60)
        self.tabs.set_visible_column_count(4)
        
        tab1 = JustifiedTextMenuItem(400, 60, self.theme, "Movies", JustifiedTextMenuItem.CENTER)
        tab1.set_userdata("movies")
        self.tabs.add_actor(tab1)
        
        tab2 = JustifiedTextMenuItem(400, 60, self.theme, "TV-Series", JustifiedTextMenuItem.CENTER)
        tab2.set_userdata("series")
        self.tabs.add_actor(tab2)
        
        #TODO: Add support for Music videos
        #tab3 = JustifiedTextMenuItem(300, 60, self.theme, "Music videos", JustifiedTextMenuItem.CENTER)
        #tab3.set_userdata("music_videos")
        #self.tabs.add_actor(tab3)
        
        tab4 = JustifiedTextMenuItem(400, 60, self.theme, "Video clips", JustifiedTextMenuItem.CENTER)
        tab4.set_userdata("clips")
        self.tabs.add_actor(tab4)
        
        self.tabs.set_position(90, 40)
        self.tabs.set_active(True)
        self.tabs.show()
        self.group.add(self.tabs)

    def _create_movies_tab(self):
        """
        Create contents of the movies tab.
        """
        self.movies_tab = clutter.Group()
        movies = self.library.get_movies()
        
        if len(movies) == 0:
            # Create warning icon
            warning = gtk.gdk.pixbuf_new_from_file(self.theme.getImage("warning_icon"))
            warning_icon = clutter.Texture()
            warning_icon.set_pixbuf(warning)
            warning_icon.set_position(383,210)
            warning_icon.show()
            self.movies_tab.add(warning_icon)
        
            # Create warning title
            info_title = clutter.Label()
            info_title.set_font_name(self.theme.getFont() + " 48px")
            info_title.set_text("No movies available!")
            info_title.set_position(460,210)
            info_title.set_color((255,255,255,255))
            info_title.show()
            self.movies_tab.add(info_title)
            
            # Create warning help text
            info = clutter.Label()
            info.set_text("""There are no indexed movies in Entertainer media library. To add movies, click on 'content' button on toolbar and open 'videos' tab. Now click on 'add' button and select some folders which contains movie files.""")
            info.set_size(690,450)
            info.set_position(390,330)
            info.set_line_wrap(True)
            info.set_font_name(self.theme.getFont() + " 32px")
            info.set_color(self.theme.getColor("menuitem_inactive"))
            info.show()
            self.movies_tab.add(info)
        else:
            #Create movie menu
            self.movie_menu = ImageMenu(self.theme)
            self.movie_menu.set_item_size(220, 350)
            self.movie_menu.set_item_spacing(20)
            self.movie_menu.set_row_count(4)
            self.movie_menu.set_orientation(self.movie_menu.VERTICAL)
            
            # Default texture
            default_cover = clutter.Texture()
            buffer = gtk.gdk.pixbuf_new_from_file(self.theme.getImage("default_movie_art"))
            default_cover.set_pixbuf(buffer)
            
            for movie in movies:
                if movie.has_cover_art():
                    texture = clutter.Texture()
                    buffer = gtk.gdk.pixbuf_new_from_file(movie.get_cover_art_url())
                    texture.set_pixbuf(buffer)
                else:
                    texture = clutter.CloneTexture(default_cover)
                
                item = ImageMenuItem(220, 350, texture)
                item.set_userdata(movie)
                self.movie_menu.add_actor(item)

            self.movie_menu.set_visible_column_count(1)
            self.movie_menu.set_position(200,150)
            self.movie_menu.set_active(False)
            self.movie_menu.show()
            
            if self.frontend.get_configuration().show_effects():
                self.movie_menu.set_animate(True)
            
            self.movies_tab.add(self.movie_menu)
            
            # Create list indicator
            self.movie_li = ListIndicator(200,34, self.theme, ListIndicator.VERTICAL)
            self.movie_li.set_position(self.ui.get_abs_x_pos(0.69), self.ui.get_abs_y_pos(0.7))
            self.movie_li.set_delimiter(" | ")
            self.movie_li.set_maximum(self.movie_menu.get_number_of_items())
            self.movie_li.set_current(1)
            self.movies_tab.add(self.movie_li)
            
            # Create information labels
            self.mi_title = clutter.Label()
            self.mi_title.set_text(" ")
            self.mi_title.set_font_name(self.theme.getFont() + ' bold 38px')
            self.mi_title.set_color(self.theme.getColor("title"))
            self.mi_title.set_line_wrap(False)
            self.mi_title.set_ellipsize(pango.ELLIPSIZE_END)
            self.mi_title.set_position(self.ui.get_abs_x_pos(0.2), self.ui.get_abs_y_pos(0.7))
            self.mi_title.set_size(650,40)
            self.mi_title.show()
            self.movies_tab.add(self.mi_title)
            
            self.mi_info = clutter.Label()
            self.mi_info.set_text(" ")
            self.mi_info.set_font_name(self.theme.getFont() + ' 32px')
            self.mi_info.set_color(self.theme.getColor("subtitle"))
            self.mi_info.set_line_wrap(False)
            self.mi_info.set_ellipsize(pango.ELLIPSIZE_END)
            self.mi_info.set_position(self.ui.get_abs_x_pos(0.2), self.ui.get_abs_y_pos(0.77))
            self.mi_info.set_size(650,40)
            self.mi_info.show()
            self.movies_tab.add(self.mi_info)
            
            self.mi_plot = clutter.Label()
            self.mi_plot.set_text("")
            self.mi_plot.set_font_name(self.theme.getFont() + ' 28px')
            self.mi_plot.set_color(self.theme.getColor("subtitle"))
            self.mi_plot.set_position(self.ui.get_abs_x_pos(0.2), self.ui.get_abs_y_pos(0.83))
            self.mi_plot.set_line_wrap_mode(pango.WRAP_WORD)
            self.mi_plot.set_line_wrap(True)
            
            self.mi_plot.show()
            self.movies_tab.add(self.mi_plot)
            
            
        self.group.add(self.movies_tab)
        
    def _create_series_tab(self):
        """
        Create contents of the TV-Series tab.
        """
        self.series_tab = clutter.Group()
        series = self.library.get_tv_series()
        if len(series) == 0:
            # Create warning icon
            warning = gtk.gdk.pixbuf_new_from_file(self.theme.getImage("warning_icon"))
            warning_icon = clutter.Texture()
            warning_icon.set_pixbuf(warning)
            warning_icon.set_position(383,210)
            warning_icon.show()
            self.series_tab.add(warning_icon)
        
            # Create warning title
            info_title = clutter.Label()
            info_title.set_font_name(self.theme.getFont() + " 48px")
            info_title.set_text("No TV-series available!")
            info_title.set_position(460,210)
            info_title.set_color((255,255,255,255))
            info_title.show()
            self.series_tab.add(info_title)
            
            # Create warning help text
            info = clutter.Label()
            info.set_text("""There are no indexed TV-series in Entertainer media library. To add TV-series, click on 'content' button on toolbar and open 'videos' tab. Now click on 'add' button and select some folders which contains video files.""")
            info.set_size(690,450)
            info.set_position(390,330)
            info.set_line_wrap(True)
            info.set_font_name(self.theme.getFont() + " 32px")
            info.set_color(self.theme.getColor("menuitem_inactive"))
            info.show()
            self.series_tab.add(info)
        else:
            #Create TV-series menu
            self.series_menu = ImageMenu(self.theme)
            self.series_menu.set_item_size(220, 350)
            self.series_menu.set_item_spacing(20)
            self.series_menu.set_row_count(4)
            self.series_menu.set_orientation(self.series_menu.VERTICAL)
            
            # Default texture
            default_cover = clutter.Texture()
            buffer = gtk.gdk.pixbuf_new_from_file(self.theme.getImage("default_movie_art"))
            default_cover.set_pixbuf(buffer)
            
            for serie in series:
                if serie.has_cover_art():
                    texture = clutter.Texture()
                    buffer = gtk.gdk.pixbuf_new_from_file(serie.get_cover_art_url())
                    texture.set_pixbuf(buffer)
                else:
                    texture = clutter.CloneTexture(default_cover)
                
                item = ImageMenuItem(220, 350, texture)
                item.set_userdata(serie)
                self.series_menu.add_actor(item)

            self.series_menu.set_visible_column_count(1)
            self.series_menu.set_position(200,150)
            self.series_menu.set_active(False)
            self.series_menu.show()

            if self.frontend.get_configuration().show_effects():
                self.series_menu.set_animate(True)
            
            self.series_tab.add(self.series_menu)
        
            # Create list indicator
            self.series_li = ListIndicator(200,34, self.theme, ListIndicator.VERTICAL)
            self.series_li.set_position(self.ui.get_abs_x_pos(0.69), self.ui.get_abs_y_pos(0.7))
            self.series_li.set_delimiter(" | ")
            self.series_li.set_maximum(self.series_menu.get_number_of_items())
            self.series_li.set_current(1)
            self.series_tab.add(self.series_li)
            
            # Create information labels
            self.serie_title = clutter.Label()
            self.serie_title.set_text(" ")
            self.serie_title.set_font_name(self.theme.getFont() + ' bold 38px')
            self.serie_title.set_color(self.theme.getColor("title"))
            self.serie_title.set_line_wrap(False)
            #self.serie_title.set_ellipsize(pango.ELLIPSIZE_END)
            self.serie_title.set_position(self.ui.get_abs_x_pos(0.2), self.ui.get_abs_y_pos(0.7))
            self.serie_title.set_size(700,40)
            self.serie_title.show()
            self.series_tab.add(self.serie_title)
            
            self.serie_info = clutter.Label()
            self.serie_info.set_text(" ")
            self.serie_info.set_font_name(self.theme.getFont() + ' 32px')
            self.serie_info.set_color(self.theme.getColor("subtitle"))
            self.serie_info.set_line_wrap(False)
            #self.serie_info.set_ellipsize(pango.ELLIPSIZE_END)
            self.serie_info.set_position(self.ui.get_abs_x_pos(0.2), self.ui.get_abs_y_pos(0.77))
            self.serie_info.set_size(700,40)
            self.serie_info.show()
            self.series_tab.add(self.serie_info)
        
        self.group.add(self.series_tab)
  
    def _create_music_videos_tab(self):
        """
        Create contents of the Music videos  tab.
        """
        self.musicvids_tab = clutter.Group()
        
        self.group.add(self.musicvids_tab)
        
    def _create_clips_tab(self):
        """
        Create contents of the Video clips tab.
        """
        self.clips_tab = clutter.Group()
        
        self.group.add(self.clips_tab)
    
    def _change_tab(self):
        """
        Change view to another tab.
        """
        self.movies_tab.hide()
        self.series_tab.hide()
        self.musicvids_tab.hide()
        self.clips_tab.hide()
        
        self.current_tab = self.tabs.get_current_menuitem().get_userdata()
        if self.current_tab == "movies":
            self.movies_tab.show()
        elif self.current_tab == "series":
            self.series_tab.show()
        elif self.current_tab == "musicvids":
            self.musicvids_tab.show()
        elif self.current_tab == "clips":
            self.clips_tab.show()
    
    def _update_series_info(self, serie):
        """
        Update TV-Serie information. Updates clutter labels on TV-series tab
        @param serie: Currently selected TV-Serie (TVSeries object)
        """
        self.serie_title.set_text(serie.get_title())
        info = str(serie.get_number_of_seasons()) + " Seasons\n" + str(serie.get_number_of_episodes()) + " Episodes"
        self.serie_info.set_text(info)
    
    def _update_movie_info(self, movie):
        """
        Update movie information. Updates clutter labels in Movie tab.
        @param movie: Currently selected movie (Movie object)
        """
        genres = movie.get_genres()
        if len(genres) > 1:
            genre = genres[0] + "/" + genres[1]
        else:
            genre = genres[0]
        self.mi_title.set_text(movie.get_title() + " (" + movie.get_year() + ")")
        self.mi_info.set_text(str(movie.get_runtime()) + "min, " + genre)
        self.mi_plot.set_text(movie.get_short_plot())
        self.mi_plot.set_line_wrap(True)
        self.mi_plot.set_size(890,50)
        #self.mi_plot.set_ellipsize(pango.ELLIPSIZE_END)
        
    def get_group(self):
        """
        Get all actors of the screen.
        @return clutter.Group 
        """
        return self.group

    def get_type(self):
        """
        Get screen type.
        @return: Integer (Constant variable from Screen class)
        """
        return Screen.NORMAL
    
    def get_name(self):
        """
        Get screen name (human readble)
        @return: String
        """
        return "VideoScreen"
    
    def handle_key_press_event(self, event):   
        """ Handle key pressed event."""
        #UP KEY
        if event.keyval == clutter.keysyms.Up:
            if self.current_tab == "movies":
                if self.movie_menu.get_current_postition() <= 3:
                    self.movie_menu.set_active(False)
                    self.tabs.set_active(True)
                    self.mi_title.hide()
                    self.mi_info.hide()
                    self.mi_plot.hide()
                    self.movie_li.hide()
                else:
                    self.movie_menu.move(self.movie_menu.UP)
                    self._update_movie_info(self.movie_menu.get_current_menuitem().get_userdata())
                    self.movie_li.set_current(self.movie_menu.get_current_postition() + 1)
            
            elif self.current_tab == "series":
                if len(self.library.get_tv_series()) == 0: # If there is no indexed tv-episodes
                    return
                if self.series_menu.get_current_postition() <= 3:
                    self.series_menu.set_active(False)
                    self.tabs.set_active(True)
                    self.serie_title.hide()
                    self.serie_info.hide()
                    self.series_li.hide()
                else:
                    self.series_menu.move(self.movie_menu.UP)
                    self._update_series_info(self.series_menu.get_current_menuitem().get_userdata())
                    self.series_li.set_current(self.series_menu.get_current_postition() + 1)
                    
            elif self.current_tab == "musicvids":
                pass
            elif self.current_tab == "clips":
                pass
        
        #DOWN KEY  
        elif event.keyval == clutter.keysyms.Down:
            # Activate tab menu if tab bar was active
            if self.tabs.is_active():
                if self.current_tab == "movies":
                    if len(self.library.get_movies()) == 0: # If there is no indexed movies
                        return
                    self.movie_menu.set_active(True)
                    self._update_movie_info(self.movie_menu.get_current_menuitem().get_userdata())
                    self.mi_title.show()
                    self.mi_info.show()
                    self.mi_plot.show()
                    self.movie_li.show()
                    
                elif self.current_tab == "series":
                    if len(self.library.get_tv_series()) == 0: # If there is no indexed tv-episodes
                        return
                    self.series_menu.set_active(True)
                    self._update_series_info(self.series_menu.get_current_menuitem().get_userdata())
                    self.serie_title.show()
                    self.serie_info.show()
                    self.series_li.show()
                    
                elif self.current_tab == "musicvids":
                    pass#self.playlist_menu.set_active(True)
                
                elif self.current_tab == "clips":
                    pass#self.genre_menu.set_active(True)
                
                self.tabs.set_active(False)
                return
            
            if self.current_tab == "movies":
                self.movie_menu.move(self.movie_menu.DOWN)
                self._update_movie_info(self.movie_menu.get_current_menuitem().get_userdata())
                self.movie_li.set_current(self.movie_menu.get_current_postition() + 1)
            elif self.current_tab == "series":
                self.series_menu.move(self.series_menu.DOWN)
                #self._update_movie_info(self.album_menu.get_current_menuitem().get_userdata())
                #self.album_li.set_current(self.album_menu.get_current_postition() + 1)
            elif self.current_tab == "musicvids":
                pass
            elif self.current_tab == "clips":
                pass
        
        #LEFT KEY
        elif event.keyval == clutter.keysyms.Left:
            if self.tabs.is_active():
                self.tabs.move(self.tabs.LEFT)
                self._change_tab()
                
            elif self.current_tab == "movies":
                self.movie_menu.move(self.movie_menu.LEFT)
                self._update_movie_info(self.movie_menu.get_current_menuitem().get_userdata())
                self.movie_li.set_current(self.movie_menu.get_current_postition() + 1)
                
            elif self.current_tab == "series":
                self.series_menu.move(self.series_menu.LEFT)
                self._update_series_info(self.series_menu.get_current_menuitem().get_userdata())
                self.series_li.set_current(self.series_menu.get_current_postition() + 1)
                
            elif self.current_tab == "musicvids":
                pass
            elif self.current_tab == "clips":
                pass
        
        # RIGHT KEY
        elif event.keyval == clutter.keysyms.Right:
            if self.tabs.is_active():
                self.tabs.move(self.tabs.RIGHT)
                self._change_tab()
                
            elif self.current_tab == "movies":
                self.movie_menu.move(self.movie_menu.RIGHT)
                self._update_movie_info(self.movie_menu.get_current_menuitem().get_userdata())
                self.movie_li.set_current(self.movie_menu.get_current_postition() + 1)
                
            elif self.current_tab == "series":
                self.series_menu.move(self.series_menu.RIGHT)
                self._update_series_info(self.series_menu.get_current_menuitem().get_userdata())
                self.series_li.set_current(self.series_menu.get_current_postition() + 1)
                
            elif self.current_tab == "musicvids":
                pass
            elif self.current_tab == "clips":
                pass
        
        # RETURN KEY
        elif event.keyval == clutter.keysyms.Return:
            if self.tabs.is_active():
                return
            
            if self.current_tab == "movies": 
                pass
                movie = self.movie_menu.get_current_menuitem().get_userdata()
                self.ui.changeScreen(self.ui.createScreen("movie", movie), Transition.FORWARD)
            elif self.current_tab == "series":
                serie = self.series_menu.get_current_menuitem().get_userdata()
                self.ui.changeScreen(self.ui.createScreen("tv-serie", serie), Transition.FORWARD)
            elif self.current_tab == "musicvids":
                pass
            elif self.current_tab == "clips":
                pass